﻿using CleanArchitecture.Core.Configuration;
using CleanArchitecture.Infrastructure.ActiveLogExtension;
using CleanArchitecture.Infrastructure.Entities.Settings;
using CleanArchitecture.Infrastructure.Interfaces.Authentication;
using CleanArchitecture.Infrastructure.Interfaces.Business;
using CleanArchitecture.Infrastructure.Interfaces.Customers;
using CleanArchitecture.Infrastructure.Models;
using CleanArchitecture.Infrastructure.Services.Captcha;
using CleanArchitecture.Web.Backend.BackendApi;
using CleanArchitecture.Web.Factories;
using CleanArchitecture.Web.Validators.Customers;
using FluentValidation.Results;
using Microsoft.AspNetCore.Mvc;

namespace CleanArchitecture.Web.Controllers.Frontend.FrontendApi
{
    public class FrontendHomeApiController : HomeController
    {
        private readonly SecuritySettings _securitySettings;
        private readonly CustomerSettings _customerSettings;
        private readonly CaptchaSettings _captchaSettings;
        private readonly IAuthenticationService _authenticationService;
        private readonly ICustomerRegistrationService _customerregistrationService;
        public FrontendHomeApiController(
            SecuritySettings securitySettings,
            CustomerSettings customerSettings,
            CaptchaSettings captchaSettings,
            IColumnService columnService,
            IBusinessModelFactory businessModelFactory,
            IAuthenticationService authenticationService,
            ICustomerRegistrationService customerregistrationService)
            : base(columnService, businessModelFactory)
        {
            this._captchaSettings = captchaSettings;
            this._securitySettings = securitySettings;
            this._customerSettings = customerSettings;
            this._authenticationService = authenticationService;
            this._customerregistrationService = customerregistrationService;
        }
        [HttpPost(FrontendApiRouteConfig.LoginApiRoute)]
        public IActionResult Login([FromBody]LoginModel model)
        {
            if (ModelState.IsValid)
            {
                if (_securitySettings.CustomerLoginVerify.Equals("passwordandcaptcha") && _captchaSettings.Enabled)
                {
                    //Validate CAPTCHA
                    var captcha = new Captcha(_captchaSettings);
                    if (!captcha.ValidateCaptchaCode(model.CaptchaCode, HttpContext))
                        return WarnJson(ApiResponseMessages.CaptchaCodeError);
                }
                string responseMsg = string.Empty;
                CustomerLoginValidator validator = new CustomerLoginValidator(_customerSettings, _securitySettings);
                ValidationResult results = validator.Validate(model);
                if (!results.IsValid)
                {
                    foreach (var failure in results.Errors)
                        responseMsg += failure.ErrorMessage + "\n";

                    return WarnJson(responseMsg);
                }
                var loginCustomer = _customerregistrationService.ValidateCustomer(model.LoginUser, model.Password, _securitySettings.CustomerLoginVerify);
                var loginResponse = new LoginResultMsg();
                if (loginCustomer.ExtraInfo is LoginResults && (LoginResults)loginCustomer.ExtraInfo == LoginResults.Successful)
                {
                    //sign in new customer
                    string jwtToken = _authenticationService.SignIn(loginCustomer);

                    //raise event    
                    if (_customerSettings.LogCustomerLoggedEvent)
                        loginCustomer.LogCustomerLoginEvent();
                    return SuccessJson(loginResponse[LoginResults.Successful], jwtToken);
                }
                //else 
                return ErrorJson(loginResponse[(LoginResults)loginCustomer.ExtraInfo]);
            }
            return ErrorJson(ApiResponseMessages.ModelBindingError);
        }

        [HttpPost(FrontendApiRouteConfig.LogoutApiRoute)]
        public IActionResult Logout()
        {
            //standard logout 
            _authenticationService.SignOut(SignInUserEnum.Customer);
            return SuccessJson(ApiResponseMessages.LogoutSuccessful);
        }
    }
}
